The packages of tidyverse help imensely with data cleaning and initial visualization. The eurostat package helps parse the open JSON api of eurostat databases.
library("tidyverse")
Loading tidyverse: ggplot2
Loading tidyverse: tibble
Loading tidyverse: tidyr
Loading tidyverse: readr
Loading tidyverse: purrr
Loading tidyverse: dplyr
Conflicts with tidy packages -----------------------------------------------------------------------------------
filter(): dplyr, stats
lag(): dplyr, stats
library("eurostat")
library(readxl)
We now extract and use the dataset from our sources. first the biggest and messiest dataset!
init.data<- data.frame(read.csv("../data/WEF_TTCR17_data_for_download.csv"))
as_tibble(init.data)
init.data
We can see that this is now viewable as a dataframe . We immediately see that there are a lot of columns and values that we just arent interested in. The analysis will entail tourism spending and other characteristics pertaining to 28 the EU member states. First order would be filter out only the relevant 28 states.
colnames(init.data) <- as.character(unlist(init.data[1,]))
init.data
To achieve our goal we first convert the header to meaningful data. We then create a column vector with the relevant columns needed and subset the data to get relevant fields for our 28 member states.
reqCol <- c('Series','Attribute','AUT', 'BEL', 'BGR', 'HRV', 'CYP', 'CZE', 'DNK', 'EST', 'FIN', 'FRA', 'DEU', 'GRC', 'HUN', 'IRL', 'ITA', 'LVA', 'LTU', 'LUX', 'MLT', 'NLD', 'POL', 'PRT', 'ROU', 'SVK', 'SVN','TUR', 'ESP', 'SWE', 'GBR')
prelimData <- init.data[,reqCol]
prelimData
WECTTCI17 <- filter(prelimData,Attribute == 'Value')
WECTTCI17
Statista <- read_excel("../data/statistic_id314340_leading-european-city-tourism-destinations-in-2017-by-number-of-bednights.xlsx",sheet = "Data",skip=4)
names(Statista) <- c('City','Count')
Statista$CountryTwo <- c("GB","FR","DE","IT","ES","ES","CZ","TR","AT","DE","NL","SE","DE","IT","PT")
Statista$CountryThree <- c("GBR","FRA","DEU","ITA","ESP","ESP","CZE","TUR","AUT","DEU","NLD","SWE","DEU","ITA","PRT")
Statista <- Statista[c(4,3,1,2)]
Statista
automated loading of datasets from eurostat to ensure up to date data on Eu residents as updated by the primary source of data collection from the EU
- Total footfalls in EU.
eutwoletter <- c("AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","GB")
byFootfall<- get_eurostat("tour_dem_extot", filters = list(nongeo=1,geo = eutwoletter,sinceTimePeriod=2012,purpose="TOTAL",precision=1,duration="N_GE1",unit="THS_EUR",partner="DOM"), time_format = "num")
byFootfall <- select(byFootfall,geo:values)
byFootfall
This data needs to cleaned and transformed into the right structure. The composite primary key we will year and geo.
year <- unique(byFootfall$time)
geo <- unique(byFootfall$geo)
geo <- as.character(geo)
footfall <- c()
for (i in 1:length(geo)) {
for (j in 1:length(year)) {
test <- filter(byFootfall,geo==geo[i],year==year[j])%>% select(values)
row <- c(year[j],geo[i],unlist(test,recursive = TRUE,use.names = FALSE))
footfall <- rbind(footfall,row)
}
}
colnames(footfall) <- c("Year","Geo","Footfall_in_mil")
write.csv(footfall,file = "Footfall.csv",row.names = FALSE)
footfall <- read.csv("Footfall.csv")
footfall
byAge<- get_eurostat("tour_dem_toage", filters = list(nongeo=1,geo = eutwoletter,sinceTimePeriod=2012,purpose="TOTAL",precision=1,duration="N_GE1",unit="NR",partner="DOM",age=c("Y_LT15","Y15-24","Y25-34","Y35-44","Y45-64","Y_GE65")), time_format = "num")
byAge <- select(byAge,age:values)
byAge
We will need to transform this data into a usabe format.
ageFactor <- unique(byAge$age)
year <- unique(byAge$time)
geo <- unique(byAge$geo)
geo <- as.character(geo)
age <- c()
for (i in 1:length(geo)) {
for (j in 1:length(year)) {
test <- filter(byAge,geo==geo[i],year==year[j])%>% select(values)
row <- c(year[j],geo[i],unlist(test,recursive = TRUE,use.names = FALSE))
age <- rbind(age,row)
}
}
colnames(age) <- c("Year","Geo","Y15-24","Y25-34","Y35-44","Y45-64","Y_GE65","Y_LT15")
write.csv(age,file = "Age.csv",row.names = FALSE)
age <- read.csv("Age.csv")
age$Y_LT15 <- NULL
age
bySex <- get_eurostat("tour_dem_tosex", filters = list(nongeo=1,geo = eutwoletter,sinceTimePeriod=2012,precision=1,duration="N_GE1",unit="NR",partner="DOM",sex=c("M","F")), time_format = "num")
bySex <- select(bySex,sex:values)
bySex
This datframe also has to be transformed with geo and time to be the composite primary key
sexFactor <- unique(bySex$sex)
year <- unique(bySex$time)
geo <- unique(bySex$geo)
geo <- as.character(geo)
sex <- c()
for (i in 1:length(geo)) {
for (j in 1:length(year)) {
test <- filter(bySex,geo==geo[i],year==year[j])%>% select(values)
row <- c(year[j],geo[i],unlist(test,recursive = TRUE,use.names = FALSE))
sex <- rbind(sex,row)
}
}
colnames(sex) <- c("Year","Geo","F","M")
write.csv(sex,file = "Sex.csv",row.names = FALSE)
Sex <- read.csv("Sex.csv")
Sex
LS0tDQp0aXRsZTogIkRhdGEgbG9hZGluZyBhbmQgQ2xlYW5pbmciDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGUgcGFja2FnZXMgb2YgdGlkeXZlcnNlIGhlbHAgaW1lbnNlbHkgd2l0aCBkYXRhIGNsZWFuaW5nIGFuZCBpbml0aWFsIHZpc3VhbGl6YXRpb24uDQpUaGUgZXVyb3N0YXQgcGFja2FnZSBoZWxwcyBwYXJzZSB0aGUgb3BlbiBKU09OIGFwaSBvZiBldXJvc3RhdCBkYXRhYmFzZXMuDQpgYGB7cn0NCmxpYnJhcnkoInRpZHl2ZXJzZSIpDQpsaWJyYXJ5KCJldXJvc3RhdCIpDQpsaWJyYXJ5KHJlYWR4bCkNCmBgYA0KDQpXZSBub3cgZXh0cmFjdCBhbmQgdXNlIHRoZSBkYXRhc2V0IGZyb20gb3VyIHNvdXJjZXMuDQpmaXJzdCB0aGUgYmlnZ2VzdCBhbmQgbWVzc2llc3QgZGF0YXNldCENCg0KYGBge3J9DQppbml0LmRhdGE8LSBkYXRhLmZyYW1lKHJlYWQuY3N2KCIuLi9kYXRhL1dFRl9UVENSMTdfZGF0YV9mb3JfZG93bmxvYWQuY3N2IikpDQphc190aWJibGUoaW5pdC5kYXRhKQ0KaW5pdC5kYXRhDQpgYGANCg0KV2UgY2FuIHNlZSB0aGF0IHRoaXMgaXMgbm93IHZpZXdhYmxlIGFzIGEgZGF0YWZyYW1lIC4gV2UgaW1tZWRpYXRlbHkgc2VlIHRoYXQgdGhlcmUgYXJlIGEgbG90IG9mIGNvbHVtbnMgYW5kIHZhbHVlcyB0aGF0IHdlIGp1c3QgYXJlbnQgaW50ZXJlc3RlZCBpbi4gVGhlIGFuYWx5c2lzIHdpbGwgZW50YWlsIHRvdXJpc20gc3BlbmRpbmcgYW5kIG90aGVyIGNoYXJhY3RlcmlzdGljcyBwZXJ0YWluaW5nIHRvIDI4IHRoZSBFVSBtZW1iZXIgc3RhdGVzLg0KRmlyc3Qgb3JkZXIgd291bGQgYmUgZmlsdGVyIG91dCBvbmx5IHRoZSByZWxldmFudCAyOCBzdGF0ZXMuDQpgYGB7cn0NCmNvbG5hbWVzKGluaXQuZGF0YSkgPC0gYXMuY2hhcmFjdGVyKHVubGlzdChpbml0LmRhdGFbMSxdKSkNCmluaXQuZGF0YQ0KYGBgDQoNClRvIGFjaGlldmUgb3VyIGdvYWwgd2UgZmlyc3QgY29udmVydCB0aGUgaGVhZGVyIHRvIG1lYW5pbmdmdWwgZGF0YS4gDQpXZSB0aGVuIGNyZWF0ZSBhIGNvbHVtbiB2ZWN0b3Igd2l0aCB0aGUgcmVsZXZhbnQgY29sdW1ucyBuZWVkZWQgYW5kIHN1YnNldCB0aGUgZGF0YSB0byBnZXQgcmVsZXZhbnQgZmllbGRzIGZvciBvdXIgMjggbWVtYmVyIHN0YXRlcy4NCg0KYGBge3J9DQpyZXFDb2wgPC0gYygnU2VyaWVzJywnQXR0cmlidXRlJywnQVVUJywgJ0JFTCcsICdCR1InLCAnSFJWJywgJ0NZUCcsICdDWkUnLCAnRE5LJywgJ0VTVCcsICdGSU4nLCAnRlJBJywgJ0RFVScsICdHUkMnLCAnSFVOJywgJ0lSTCcsICdJVEEnLCAnTFZBJywgJ0xUVScsICdMVVgnLCAnTUxUJywgJ05MRCcsICdQT0wnLCAnUFJUJywgJ1JPVScsICdTVksnLCAnU1ZOJywnVFVSJywgJ0VTUCcsICdTV0UnLCAnR0JSJykNCnByZWxpbURhdGEgPC0gaW5pdC5kYXRhWyxyZXFDb2xdDQpwcmVsaW1EYXRhDQpgYGANCg0KYGBge3J9DQpXRUNUVENJMTcgPC0gZmlsdGVyKHByZWxpbURhdGEsQXR0cmlidXRlID09ICdWYWx1ZScpDQpXRUNUVENJMTcNCmBgYA0KDQpgYGB7cn0NCldFQ1RUQ0kxNyA8LSBzZWxlY3QoV0VDVFRDSTE3LC0oQXR0cmlidXRlKSkNCldFQ1RUQ0kxNyRTZXJpZXMgPC0gZ3N1YigiLCIsIiIsV0VDVFRDSTE3JFNlcmllcykNCldFQ1RUQ0kxNyA8LSBXRUNUVENJMTdbLWMoOCksXQ0KV0VDVFRDSTE3IDwtIHQoV0VDVFRDSTE3KQ0KV0VDVFRDSTE3IDwtYXMuZGF0YS5mcmFtZShXRUNUVENJMTcpDQpjb2wgPC0gYyg2LDI1LDI3OjMxLDM4LDQxLDQzLDUwLDUyLDUzLDU1LDU2LDgwOjkwKQ0KV0VDVFRDSTE3IDwtIHNlbGVjdChXRUNUVENJMTcsY29sKQ0KY29sbmFtZXMoV0VDVFRDSTE3KSA8LSBhcy5jaGFyYWN0ZXIodW5saXN0KFdFQ1RUQ0kxN1sxLF0pKQ0KV0VDVFRDSTE3JHllYXIgPC0gIGMoMjAxNykNCldFQ1RUQ0kxNyA8LSBXRUNUVENJMTdbYygyNywxOjI2KV0NCldFQ1RUQ0kxNyA8LSBXRUNUVENJMTdbLC1jKDkpXQ0KV0VDVFRDSTE3IDwtIFdFQ1RUQ0kxN1stYygxKSxdDQp3cml0ZS5jc3YoV0VDVFRDSTE3LGZpbGUgPSAiaW50ZXJpbVdlYy5jc3YiLHJvdy5uYW1lcyA9IFRSVUUpDQpXRUNUVENJMTcgPC0gcmVhZC5jc3YoImludGVyaW1XZWMuY3N2IikNCmNvbG5hbWVzKFdFQ1RUQ0kxNykgPC0gYygiY291bnRyeSIsInllYXIiLCJnZHBfc2hhcmUiLCJ0ZXJyb3Jpc21fY29zdCIsImhvbWljaWRlcyIsInBoeXNpY2lhbiIsImltcHJvdmVkX3Nhbml0YXRpb24iLCJpbXByb3ZlZF93YXRlciIsImhvc3BpdGFsIiwicGF5IiwiaWN0IiwiZWxlY3RyaWNpdHkiLCJ0b3VyaXNtX3NwZW50IiwibWFya2V0aW5nX2VmZmVjdGl2ZW5lcyIsIm9wZW5fZGF0YSIsImJyYW5kX3JhdGluZyIsInJvYWRzIiwicmFpbHJvYWQiLCJwb3J0IiwiZ3JvdW5kX3RyYW5zcG9ydCIsInJhaWxyb2FkX2RlbnNpdHkiLCJob3RlbF9yb29tcyIsInRvdXJpc21faW5mcmEiLCJjYXJfcmVudGFsIiwiYXRtIiwiaGVyaXRhZ2Vfc2l0ZXMiLCJzcGVjaWVzIikNCndyaXRlLmNzdihXRUNUVENJMTcsZmlsZSA9ICJXRUNUVENJLmNzdiIscm93Lm5hbWVzID0gRkFMU0UpDQpXRUNUVENJMTcNCmBgYA0KDQpgYGB7cn0NClN0YXRpc3RhIDwtIHJlYWRfZXhjZWwoIi4uL2RhdGEvc3RhdGlzdGljX2lkMzE0MzQwX2xlYWRpbmctZXVyb3BlYW4tY2l0eS10b3VyaXNtLWRlc3RpbmF0aW9ucy1pbi0yMDE3LWJ5LW51bWJlci1vZi1iZWRuaWdodHMueGxzeCIsc2hlZXQgPSAiRGF0YSIsc2tpcD00KQ0KbmFtZXMoU3RhdGlzdGEpIDwtIGMoJ0NpdHknLCdDb3VudCcpDQpTdGF0aXN0YSRDb3VudHJ5VHdvIDwtIGMoIkdCIiwiRlIiLCJERSIsIklUIiwiRVMiLCJFUyIsIkNaIiwiVFIiLCJBVCIsIkRFIiwiTkwiLCJTRSIsIkRFIiwiSVQiLCJQVCIpDQpTdGF0aXN0YSRDb3VudHJ5VGhyZWUgPC0gYygiR0JSIiwiRlJBIiwiREVVIiwiSVRBIiwiRVNQIiwiRVNQIiwiQ1pFIiwiVFVSIiwiQVVUIiwiREVVIiwiTkxEIiwiU1dFIiwiREVVIiwiSVRBIiwiUFJUIikNClN0YXRpc3RhIDwtIFN0YXRpc3RhW2MoNCwzLDEsMildDQp3cml0ZS5jc3YoU3RhdGlzdGEsZmlsZSA9ICJTdGF0aXN0YS5jc3YiKQ0KU3RhdGlzdGENCmBgYA0KDQphdXRvbWF0ZWQgbG9hZGluZyBvZiBkYXRhc2V0cyBmcm9tIGV1cm9zdGF0IHRvIGVuc3VyZSB1cCB0byBkYXRlIGRhdGEgb24gRXUgcmVzaWRlbnRzIGFzIHVwZGF0ZWQgYnkgdGhlIHByaW1hcnkgc291cmNlIG9mIGRhdGEgY29sbGVjdGlvbiBmcm9tIHRoZSBFVQ0KDQoxLiBUb3RhbCBmb290ZmFsbHMgaW4gRVUuDQpgYGB7cn0NCmV1dHdvbGV0dGVyIDwtIGMoIkFUIiwiQkUiLCJCRyIsIkhSIiwiQ1kiLCJDWiIsIkRLIiwiRUUiLCJGSSIsIkZSIiwiREUiLCJHUiIsIkhVIiwiSUUiLCJJVCIsIkxWIiwiTFQiLCJMVSIsIk1UIiwiTkwiLCJQTCIsIlBUIiwiUk8iLCJTSyIsIlNJIiwiRVMiLCJTRSIsIkdCIikNCmJ5Rm9vdGZhbGw8LSBnZXRfZXVyb3N0YXQoInRvdXJfZGVtX2V4dG90IiwgZmlsdGVycyA9IGxpc3Qobm9uZ2VvPTEsZ2VvID0gZXV0d29sZXR0ZXIsc2luY2VUaW1lUGVyaW9kPTIwMTIscHVycG9zZT0iVE9UQUwiLHByZWNpc2lvbj0xLGR1cmF0aW9uPSJOX0dFMSIsdW5pdD0iVEhTX0VVUiIscGFydG5lcj0iRE9NIiksIHRpbWVfZm9ybWF0ID0gIm51bSIpDQpieUZvb3RmYWxsIDwtIHNlbGVjdChieUZvb3RmYWxsLGdlbzp2YWx1ZXMpDQpieUZvb3RmYWxsDQpgYGANClRoaXMgZGF0YSBuZWVkcyB0byBjbGVhbmVkIGFuZCB0cmFuc2Zvcm1lZCBpbnRvIHRoZSByaWdodCBzdHJ1Y3R1cmUuIFRoZSBjb21wb3NpdGUgcHJpbWFyeSBrZXkgd2Ugd2lsbCB5ZWFyIGFuZCBnZW8uDQpgYGB7cn0NCnllYXIgPC0gdW5pcXVlKGJ5Rm9vdGZhbGwkdGltZSkNCmdlbyA8LSB1bmlxdWUoYnlGb290ZmFsbCRnZW8pDQoNCmdlbyA8LSBhcy5jaGFyYWN0ZXIoZ2VvKQ0KZm9vdGZhbGwgPC0gYygpDQoNCmZvciAoaSBpbiAxOmxlbmd0aChnZW8pKSB7DQogIGZvciAoaiBpbiAxOmxlbmd0aCh5ZWFyKSkgew0KICAgIHRlc3QgPC0gZmlsdGVyKGJ5Rm9vdGZhbGwsZ2VvPT1nZW9baV0seWVhcj09eWVhcltqXSklPiUgc2VsZWN0KHZhbHVlcykNCiAgICByb3cgPC0gYyh5ZWFyW2pdLGdlb1tpXSx1bmxpc3QodGVzdCxyZWN1cnNpdmUgPSBUUlVFLHVzZS5uYW1lcyA9IEZBTFNFKSkNCiAgICBmb290ZmFsbCA8LSByYmluZChmb290ZmFsbCxyb3cpDQogICAgDQogIH0NCn0NCg0KY29sbmFtZXMoZm9vdGZhbGwpIDwtIGMoIlllYXIiLCJHZW8iLCJGb290ZmFsbF9pbl9taWwiKQ0Kd3JpdGUuY3N2KGZvb3RmYWxsLGZpbGUgPSAiRm9vdGZhbGwuY3N2Iixyb3cubmFtZXMgPSBGQUxTRSkNCmZvb3RmYWxsIDwtIHJlYWQuY3N2KCJGb290ZmFsbC5jc3YiKQ0KZm9vdGZhbGwNCmBgYA0KDQpgYGB7cn0NCmJ5QWdlPC0gZ2V0X2V1cm9zdGF0KCJ0b3VyX2RlbV90b2FnZSIsIGZpbHRlcnMgPSBsaXN0KG5vbmdlbz0xLGdlbyA9IGV1dHdvbGV0dGVyLHNpbmNlVGltZVBlcmlvZD0yMDEyLHB1cnBvc2U9IlRPVEFMIixwcmVjaXNpb249MSxkdXJhdGlvbj0iTl9HRTEiLHVuaXQ9Ik5SIixwYXJ0bmVyPSJET00iLGFnZT1jKCJZMTUtMjQiLCJZMjUtMzQiLCJZMzUtNDQiLCJZNDUtNjQiLCJZX0dFNjUiKSksIHRpbWVfZm9ybWF0ID0gIm51bSIpDQpieUFnZSA8LSBzZWxlY3QoYnlBZ2UsYWdlOnZhbHVlcykNCmJ5QWdlDQpgYGANCldlIHdpbGwgbmVlZCB0byB0cmFuc2Zvcm0gdGhpcyBkYXRhIGludG8gYSB1c2FiZSBmb3JtYXQuDQoNCmBgYHtyfQ0KYWdlRmFjdG9yIDwtIHVuaXF1ZShieUFnZSRhZ2UpDQp5ZWFyIDwtIHVuaXF1ZShieUFnZSR0aW1lKQ0KZ2VvIDwtIHVuaXF1ZShieUFnZSRnZW8pDQoNCmdlbyA8LSBhcy5jaGFyYWN0ZXIoZ2VvKQ0KYWdlIDwtIGMoKQ0KDQpmb3IgKGkgaW4gMTpsZW5ndGgoZ2VvKSkgew0KICBmb3IgKGogaW4gMTpsZW5ndGgoeWVhcikpIHsNCiAgICB0ZXN0IDwtIGZpbHRlcihieUFnZSxnZW89PWdlb1tpXSx5ZWFyPT15ZWFyW2pdKSU+JSBzZWxlY3QodmFsdWVzKQ0KICAgIHJvdyA8LSBjKHllYXJbal0sZ2VvW2ldLHVubGlzdCh0ZXN0LHJlY3Vyc2l2ZSA9IFRSVUUsdXNlLm5hbWVzID0gRkFMU0UpKQ0KICAgIGFnZSA8LSByYmluZChhZ2Uscm93KQ0KICAgIA0KICB9DQp9DQpjb2xuYW1lcyhhZ2UpIDwtIGMoIlllYXIiLCJHZW8iLCJZMTUtMjQiLCJZMjUtMzQiLCJZMzUtNDQiLCJZNDUtNjQiLCJZX0dFNjUiKQ0Kd3JpdGUuY3N2KGFnZSxmaWxlID0gIkFnZS5jc3YiLHJvdy5uYW1lcyA9IEZBTFNFKQ0KYWdlIDwtIHJlYWQuY3N2KCJBZ2UuY3N2IikNCmFnZQ0KYGBgDQoNCg0KDQoNCmBgYHtyfQ0KYnlTZXggPC0gZ2V0X2V1cm9zdGF0KCJ0b3VyX2RlbV90b3NleCIsIGZpbHRlcnMgPSBsaXN0KG5vbmdlbz0xLGdlbyA9IGV1dHdvbGV0dGVyLHNpbmNlVGltZVBlcmlvZD0yMDEyLHByZWNpc2lvbj0xLGR1cmF0aW9uPSJOX0dFMSIsdW5pdD0iTlIiLHBhcnRuZXI9IkRPTSIsc2V4PWMoIk0iLCJGIikpLCB0aW1lX2Zvcm1hdCA9ICJudW0iKQ0KYnlTZXggPC0gc2VsZWN0KGJ5U2V4LHNleDp2YWx1ZXMpDQpieVNleA0KYGBgDQoNClRoaXMgZGF0ZnJhbWUgYWxzbyBoYXMgdG8gYmUgdHJhbnNmb3JtZWQgd2l0aCBnZW8gYW5kIHRpbWUgdG8gYmUgdGhlIGNvbXBvc2l0ZSBwcmltYXJ5IGtleQ0KYGBge3J9DQpzZXhGYWN0b3IgPC0gdW5pcXVlKGJ5U2V4JHNleCkNCnllYXIgPC0gdW5pcXVlKGJ5U2V4JHRpbWUpDQpnZW8gPC0gdW5pcXVlKGJ5U2V4JGdlbykNCg0KZ2VvIDwtIGFzLmNoYXJhY3RlcihnZW8pDQpzZXggPC0gYygpDQoNCmZvciAoaSBpbiAxOmxlbmd0aChnZW8pKSB7DQogIGZvciAoaiBpbiAxOmxlbmd0aCh5ZWFyKSkgew0KICAgIHRlc3QgPC0gZmlsdGVyKGJ5U2V4LGdlbz09Z2VvW2ldLHllYXI9PXllYXJbal0pJT4lIHNlbGVjdCh2YWx1ZXMpDQogICAgcm93IDwtIGMoeWVhcltqXSxnZW9baV0sdW5saXN0KHRlc3QscmVjdXJzaXZlID0gVFJVRSx1c2UubmFtZXMgPSBGQUxTRSkpDQogICAgc2V4IDwtIHJiaW5kKHNleCxyb3cpDQogICAgDQogIH0NCn0NCmNvbG5hbWVzKHNleCkgPC0gYygiWWVhciIsIkdlbyIsIkYiLCJNIikNCndyaXRlLmNzdihzZXgsZmlsZSA9ICJTZXguY3N2Iixyb3cubmFtZXMgPSBGQUxTRSkNClNleCA8LSByZWFkLmNzdigiU2V4LmNzdiIpDQpTZXgNCmBgYA0KDQo=